package com.zyuec.common;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.alibaba.fastjson.JSONObject;

/**
 * String工具类
 */
public class StringUtil {

    private Random random;
    private BufferedImage image;
    private Font font;
    private int distance;



    public static String getExcelNameByNum(int i) {
        int hashNum = "A".hashCode() - "0".hashCode();
        int sumHash = "A".hashCode() + i;
        int maxHash = "Z".hashCode();
        int cha = sumHash - maxHash;
        int s = cha / 26;
        int y = cha % 26;
        String sc = "";
        String yc = "";
        if (cha > 0) {
            if(y == 0){
                sc = (char) ("A".hashCode() + s - 1) + "";
                yc = (char) ("A".hashCode() + y + 25) + "";
            } else {
                sc = (char) ("A".hashCode() + s) + "";
                yc = (char) ("A".hashCode() + y -1) + "";
            }
        } else {
            return (char) ("A".hashCode() + i) + "";
        }
        return sc + yc;

    }

    /**
     * id 14位日期+id+3位随机数
     *
     * @param id
     * @return
     */
    public static Long genLongId(Long id) {
        String subject = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        subject += String.valueOf(id);
        String ran = randomNum(3,1);
        subject += ran;
        return Long.valueOf(subject);
    }

    /**
     * 随机数
     *
     * @param length
     *            随机数长度
     * @param type
     *            类型：0、字符1、数字2、字符+数字
     * @return
     */
    public static String randomNum(int length, int type) {
        String base = "";
        if (type == 0) {
            base = "abcdefghijklmnopqrstuvwxyz";
        } else if (type == 1) {
            base = "0123456789";
        } else if (type == 2) {
            base = "abcdefghijklmnopqrstuvwxyz0123456789";
        }
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }

        return sb.toString();
    }

    /**
     * 调账流水号 14位日期+id的后3位
     *
     * @param id
     * @return
     */
    public static String genTranNo(Long id) {
        String subject = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String orderId = String.valueOf(id);
        int length = orderId.length();

        if (length >= 3) {
            subject += orderId.substring(length - 3, length);
        } else {
            StringBuilder sb = new StringBuilder(orderId);
            sb.reverse();
            for (int i = 0; i < 3 - length; i++) {
                sb.append("0");
            }
            sb.reverse();
            subject += sb.toString();
        }

        return subject;
    }

    /**
     * 根据用户ID及订单号信息等信息生成唯一订单号
     *
     * @param @param  loginid 用户登陆ID
     * @param @param  flag 操作标志位
     * @param @param  orderId 表主键
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title: 根据当前时间到秒级+登陆ID+标志位+当前表主键4位流水号
     */
    public static String gainTranNo(Long loginId, String flag, Long orderId) {
        String subject = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String loginid = String.valueOf(loginId);
        String orderNoStr = String.valueOf(orderId);
        // 判断登陆ID位数是否超过9位
        if (loginid.length() >= 9) {
            loginid = loginid.substring(loginid.length() - 9, loginid.length());
        } else {
            StringBuilder sb = new StringBuilder(loginid);
            sb.reverse();
            for (int i = 0; i < 9 - loginid.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            loginid = sb.toString();
        }

        // 判断标志位数是否超过2位
        if (flag.length() >= 2) {
            flag = flag.substring(flag.length() - 2, flag.length());
        } else {
            StringBuilder sb = new StringBuilder(flag);
            sb.reverse();
            for (int i = 0; i < 2 - flag.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            flag = sb.toString();
        }
        // 判断订单号数是否超过4位
        if (orderNoStr.length() >= 4) {
            orderNoStr = orderNoStr.substring(orderNoStr.length() - 4, orderNoStr.length());
        } else {
            StringBuilder sb = new StringBuilder(orderNoStr);
            sb.reverse();
            for (int i = 0; i < 4 - orderNoStr.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            orderNoStr = sb.toString();
        }

        return subject + loginid + flag + orderNoStr;
    }

    /**
     * 根据用户ID及订单号信息等信息生成唯一订单号
     *
     * @param @param  loginid 用户登陆ID
     * @param @param  flag 操作标志位
     * @param @param  orderId 表主键
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title: 根据当前时间到秒级+商户编号+标志位+当前表主键4位流水号
     */
    public static String gainMerchNo(String merchNo, String flag, Long orderId) {
        String subject = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String orderNoStr = String.valueOf(orderId);
        // 判断登陆ID位数是否超过9位
        if (merchNo.length() >= 9) {
            merchNo = merchNo.substring(merchNo.length() - 9, merchNo.length());
        } else {
            StringBuilder sb = new StringBuilder(merchNo);
            sb.reverse();
            for (int i = 0; i < 9 - merchNo.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            merchNo = sb.toString();
        }

        // 判断标志位数是否超过2位
        if (flag.length() >= 2) {
            flag = flag.substring(flag.length() - 2, flag.length());
        } else {
            StringBuilder sb = new StringBuilder(flag);
            sb.reverse();
            for (int i = 0; i < 2 - flag.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            flag = sb.toString();
        }
        // 判断订单号数是否超过4位
        if (orderNoStr.length() >= 4) {
            orderNoStr = orderNoStr.substring(orderNoStr.length() - 4, orderNoStr.length());
        } else {
            StringBuilder sb = new StringBuilder(orderNoStr);
            sb.reverse();
            for (int i = 0; i < 4 - orderNoStr.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            orderNoStr = sb.toString();
        }

        return subject + merchNo + flag + orderNoStr;
    }

    /**
     * 根据商户号及订单号信息等信息生成唯一商户签约订单号
     *
     * @param @param  merchNo 商户号
     * @param @param  flag 操作标志位
     * @param @param  orderId 表主键
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title: 根据当前时间到秒级+商户编号+标志位+当前表主键4位流水号
     */
    public static String gainMerchOrderNo(String merchNo, String flag, Long orderId) {
        String subject = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String orderNoStr = String.valueOf(orderId);
        // 判断登陆ID位数是否超过9位
        if (merchNo.length() >= 9) {
            merchNo = merchNo.substring(merchNo.length() - 9, merchNo.length());
        } else {
            StringBuilder sb = new StringBuilder(merchNo);
            sb.reverse();
            for (int i = 0; i < 9 - merchNo.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            merchNo = sb.toString();
        }

        // 判断标志位数是否超过2位
        if (flag.length() >= 2) {
            flag = flag.substring(flag.length() - 2, flag.length());
        } else {
            StringBuilder sb = new StringBuilder(flag);
            sb.reverse();
            for (int i = 0; i < 2 - flag.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            flag = sb.toString();
        }
        // 判断订单号数是否超过4位
        if (orderNoStr.length() >= 4) {
            orderNoStr = orderNoStr.substring(orderNoStr.length() - 4, orderNoStr.length());
        } else {
            StringBuilder sb = new StringBuilder(orderNoStr);
            sb.reverse();
            for (int i = 0; i < 4 - orderNoStr.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            orderNoStr = sb.toString();
        }

        return subject + merchNo + flag + orderNoStr;
    }

    /**
     * 根据用户ID生成商户号生成规则
     *
     * @param @param  loginid 用户登陆ID
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title: ZY+yyyy+用户登陆ID截取六位不够补零+MMddHHmm
     */
    public static String gainMerchantNo(Long loginId) {
        String subject = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
        String loginid = String.valueOf(loginId);
        // 判断登陆ID位数是否超过9位
        if (loginid.length() >= 6) {
            loginid = loginid.substring(loginid.length() - 6, loginid.length());
        } else {
            StringBuilder sb = new StringBuilder(loginid);
            sb.reverse();
            for (int i = 0; i < 6 - loginid.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            loginid = sb.toString();
        }
        return "ZY" + subject.substring(0, 4) + loginid + subject.substring(4, subject.length());
    }

    /**
     * 根据用户ID生成秘钥生成规则 create_time格式yyyyMMddHHmm
     *
     * @param @param  loginid 用户登陆ID
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title: MD5(login_id+create_time+公司名称+1pay1)
     */
    public static String gainSecretkey(Long loginId, String createTime, String merchantName) {
        String loginid = String.valueOf(loginId);
        MD5 md5 = new MD5();
        return md5.getMD5ofStr(loginid + createTime + merchantName + "1pay1");
    }

    /**
     * 根据订单表主键生成自交易订单号
     *
     * @param @param  flag 操作标志位
     * @param @param  orderId 表主键
     * @param @return 设定文件
     * @return 返回类型
     * @throws 交易类型 ：0通道费；1 分润；2子交易补款 ；8退款
     * @Title: 根据当前时间到秒级+标志位+当前表主键4位流水号
     */
    public static String gainSubNo(String flag, Long orderId) {
        String sutime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String orderNoStr = String.valueOf(orderId);
        // 判断标志位数是否超过2位
        if (flag.length() >= 2) {
            flag = flag.substring(flag.length() - 2, flag.length());
        } else {
            StringBuilder sb = new StringBuilder(flag);
            sb.reverse();
            for (int i = 0; i < 2 - flag.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            flag = sb.toString();
        }
        // 判断订单号数是否超过4位
        if (orderNoStr.length() >= 4) {
            orderNoStr = orderNoStr.substring(orderNoStr.length() - 4, orderNoStr.length());
        } else {
            StringBuilder sb = new StringBuilder(orderNoStr);
            sb.reverse();
            for (int i = 0; i < 4 - orderNoStr.length(); i++) {
                sb.append("0");
            }
            sb.reverse();
            orderNoStr = sb.toString();
        }

        return sutime + flag + orderNoStr;
    }

    public static final String getEncodeValue(String str) {
        if (isEmpty(str)) {
            return str;
        }
        try {
            return URLEncoder.encode(str, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return str;
        }
    }

    public static final String getDecodeValue(String str) {
        if (isEmpty(str)) {
            return str;
        }
        try {
            return URLDecoder.decode(str, "utf-8");
        } catch (UnsupportedEncodingException e) {
            return str;
        }
    }

    // 加密
    public static String getBase64(String str) {
        byte[] b = null;
        String s = null;
        try {
            b = str.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (b != null) {
            s = new BASE64Encoder().encode(b);
        }
        return s;
    }

    // 解密
    public static String getFromBase64(String s) {
        byte[] b = null;
        String result = null;
        if (s != null) {
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                b = decoder.decodeBuffer(s);
                result = new String(b, "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 检查字符串是否为<code>null</code>或空字符串<code>""</code>。
     * <p/>
     * <pre>
     * StringUtil.isEmpty(null)      = true
     * StringUtil.isEmpty(&quot;&quot;)        = true
     * StringUtil.isEmpty(&quot; &quot;)       = false
     * StringUtil.isEmpty(&quot;bob&quot;)     = false
     * StringUtil.isEmpty(&quot;  bob  &quot;) = false
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果为空, 则返回<code>true</code>
     */
    public static boolean isEmpty(String str) {
        return ((str == null) || (str.length() == 0));
    }

    /**
     * 检查字符串是否不是<code>null</code>和空字符串<code>""</code>。
     * <p/>
     * <pre>
     * StringUtil.isEmpty(null)      = false
     * StringUtil.isEmpty(&quot;&quot;)        = false
     * StringUtil.isEmpty(&quot; &quot;)       = true
     * StringUtil.isEmpty(&quot;bob&quot;)     = true
     * StringUtil.isEmpty(&quot;  bob  &quot;) = true
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果不为空, 则返回<code>true</code>
     */
    public static boolean isNotEmpty(String str) {
        return ((str != null) && (str.length() > 0));
    }

    /**
     * 解析Double类型
     *
     * @param str
     * @return
     */
    public static Double parseDouble(String str) {
        if (StringUtil.isEmpty(str)) {
            return 0.0;
        }
        try {
            return Double.parseDouble(str);
        } catch (Exception ex) {
            return 0.0;
        }
    }

    /**
     * 解析int类型
     */
    public static int parseInt(String str, int defaultVal) {
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
            return defaultVal;
        }
    }

    /**
     * 解析long类型
     */
    public static Long parseLong(String str) {
        try {
            return Long.parseLong(str);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 保留两位小数（不四舍五入）
     *
     * @param d
     * @return
     */
    public static String formatDouble(Double d) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#0.00");
        return df.format(d);
    }

    /**
     * 保留两位小数（四舍五入）
     *
     * @param d
     * @return
     */
    public static String formatDouble(double d) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#0.00");
        double a = new BigDecimal(d).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return df.format(a);
    }

    /**
     * 保留两位小数（四舍五入）
     *
     * @param d
     * @return
     */
    public static double stringToDouble(double d) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#0.00");
        double a = new BigDecimal(d).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return Double.valueOf(df.format(a)).doubleValue();
    }

    /**
     * 判断是否为全数字 正整数
     *
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
        Pattern p = Pattern.compile("^[0-9]\\d+$");
        return p.matcher(str).find();
    }

    /**
     * 判断是否为数字类型 包括带小数点
     *
     * @param str
     * @return
     */
    public static boolean isNumberAll(String str) {
        Pattern p = Pattern.compile("^(-|\\+)?\\d+(\\.\\d+)?$");// [0-9]\\d*\\.?\\d+$
        return p.matcher(str).find();
    }

    /**
     * 检查字符串是否是空白：<code>null</code>、空字符串<code>""</code>或只有空白字符。
     * <p/>
     * <pre>
     * StringUtil.isBlank(null)      = true
     * StringUtil.isBlank(&quot;&quot;)        = true
     * StringUtil.isBlank(&quot; &quot;)       = true
     * StringUtil.isBlank(&quot;bob&quot;)     = false
     * StringUtil.isBlank(&quot;  bob  &quot;) = false
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果为空白, 则返回<code>true</code>
     */
    public static boolean isBlank(String str) {
        int length;

        if ((str == null) || ((length = str.length()) == 0)) {
            return true;
        }

        for (int i = 0; i < length; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查字符串是否不是空白：<code>null</code>、空字符串<code>""</code>或只有空白字符。
     * <p/>
     * <pre>
     * StringUtil.isBlank(null)      = false
     * StringUtil.isBlank(&quot;&quot;)        = false
     * StringUtil.isBlank(&quot; &quot;)       = false
     * StringUtil.isBlank(&quot;bob&quot;)     = true
     * StringUtil.isBlank(&quot;  bob  &quot;) = true
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果为空白, 则返回<code>true</code>
     */
    public static boolean isNotBlank(String str) {
        int length;

        if ((str == null) || ((length = str.length()) == 0)) {
            return false;
        }

        for (int i = 0; i < length; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断字符串是否只包含unicode数字。
     * <p/>
     * <p>
     * <code>null</code>将返回<code>false</code>，空字符串<code>""</code>将返回
     * <code>true</code>。
     * </p>
     * <p/>
     * <pre>
     * StringUtil.isNumeric(null)   = false
     * StringUtil.isNumeric(&quot;&quot;)     = true
     * StringUtil.isNumeric(&quot;  &quot;)   = false
     * StringUtil.isNumeric(&quot;123&quot;)  = true
     * StringUtil.isNumeric(&quot;12 3&quot;) = false
     * StringUtil.isNumeric(&quot;ab2c&quot;) = false
     * StringUtil.isNumeric(&quot;12-3&quot;) = false
     * StringUtil.isNumeric(&quot;12.3&quot;) = false
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果字符串非<code>null</code>并且全由unicode数字组成，则返回<code>true</code>
     */
    public static boolean isNumeric(String str) {
        if (str == null) {
            return false;
        }

        int length = str.length();

        for (int i = 0; i < length; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断字符串是否只包含unicode数字和空格<code>' '</code>。
     * <p/>
     * <p>
     * <code>null</code>将返回<code>false</code>，空字符串<code>""</code>将返回
     * <code>true</code>。
     * </p>
     * <p/>
     * <pre>
     * StringUtil.isNumericSpace(null)   = false
     * StringUtil.isNumericSpace(&quot;&quot;)     = true
     * StringUtil.isNumericSpace(&quot;  &quot;)   = true
     * StringUtil.isNumericSpace(&quot;123&quot;)  = true
     * StringUtil.isNumericSpace(&quot;12 3&quot;) = true
     * StringUtil.isNumericSpace(&quot;ab2c&quot;) = false
     * StringUtil.isNumericSpace(&quot;12-3&quot;) = false
     * StringUtil.isNumericSpace(&quot;12.3&quot;) = false
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果字符串非<code>null</code>并且全由unicode数字和空格组成，则返回<code>true</code>
     */
    public static boolean isNumericSpace(String str) {
        if (str == null) {
            return false;
        }

        int length = str.length();

        for (int i = 0; i < length; i++) {
            if (!Character.isDigit(str.charAt(i)) && (str.charAt(i) != ' ')) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断字符串是否只包含unicode空白。
     * <p/>
     * <p>
     * <code>null</code>将返回<code>false</code>，空字符串<code>""</code>将返回
     * <code>true</code>。
     * </p>
     * <p/>
     * <pre>
     * StringUtil.isWhitespace(null)   = false
     * StringUtil.isWhitespace(&quot;&quot;)     = true
     * StringUtil.isWhitespace(&quot;  &quot;)   = true
     * StringUtil.isWhitespace(&quot;abc&quot;)  = false
     * StringUtil.isWhitespace(&quot;ab2c&quot;) = false
     * StringUtil.isWhitespace(&quot;ab-c&quot;) = false
     * </pre>
     *
     * @param str 要检查的字符串
     * @return 如果字符串非<code>null</code>并且全由unicode空白组成，则返回<code>true</code>
     */
    public static boolean isWhitespace(String str) {
        if (str == null) {
            return false;
        }

        int length = str.length();

        for (int i = 0; i < length; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 将字符串转换成大写。
     * <p/>
     * <p>
     * 如果字符串是<code>null</code>则返回<code>null</code>。
     * <p/>
     * <pre>
     * StringUtil.toUpperCase(null)  = null
     * StringUtil.toUpperCase(&quot;&quot;)    = &quot;&quot;
     * StringUtil.toUpperCase(&quot;aBc&quot;) = &quot;ABC&quot;
     * </pre>
     * <p/>
     * </p>
     *
     * @param str 要转换的字符串
     * @return 大写字符串，如果原字符串为<code>null</code>，则返回<code>null</code>
     */
    public static String toUpperCase(String str) {
        if (str == null) {
            return null;
        }

        return str.toUpperCase();
    }

    /**
     * 将字符串转换成小写。
     * <p/>
     * <p>
     * 如果字符串是<code>null</code>则返回<code>null</code>。
     * <p/>
     * <pre>
     * StringUtil.toLowerCase(null)  = null
     * StringUtil.toLowerCase(&quot;&quot;)    = &quot;&quot;
     * StringUtil.toLowerCase(&quot;aBc&quot;) = &quot;abc&quot;
     * </pre>
     * <p/>
     * </p>
     *
     * @param str 要转换的字符串
     * @return 大写字符串，如果原字符串为<code>null</code>，则返回<code>null</code>
     */
    public static String toLowerCase(String str) {
        if (str == null) {
            return null;
        }

        return str.toLowerCase();
    }

    // =========================================validCode====================================================

    public static boolean sql_inj(String str) {
        String inj_str = "'#and#exec#insert#select#delete#update#count#*#%#chr#mid#master#truncate#char#declare#;#or#-#+#,";
        String[] inj_stra = inj_str.split("#");
        for (int i = 0; i < inj_stra.length; i++) {
            if (str.indexOf(inj_stra[i]) > 0) {
                return true;
            }
        }
        return false;
    }

    public String getCheckCodeImage(String str, int show, OutputStream output) throws IOException {
        this.random = new Random();
        this.image = new BufferedImage(63, 25, 5);
        this.font = new Font("Arial", 0, 22);
        this.distance = 15;
        Graphics d = this.image.getGraphics();
        d.setColor(Color.LIGHT_GRAY);
        d.fillRect(0, 0, this.image.getWidth(), this.image.getHeight());
        d.setColor(new Color(this.random.nextInt(100) + 100, this.random.nextInt(100) + 150,
                this.random.nextInt(100) + 100));

        for (int i = 0; i < 10; i++) {
            d.drawLine(this.random.nextInt(this.image.getWidth()), this.random.nextInt(this.image.getHeight()),
                    this.random.nextInt(this.image.getWidth()), this.random.nextInt(this.image.getHeight()));
        }
        d.setColor(Color.BLACK);
        d.setFont(this.font);
        String checkCode = "";
        char tmp = '\000';
        int x = -this.distance;
        for (int i = 0; i < show; i++) {
            tmp = str.charAt(this.random.nextInt(str.length() - 1));
            checkCode = checkCode + tmp;
            x += this.distance;

            d.setColor(Color.BLACK);
            d.drawString("" + tmp, x,
                    this.random.nextInt(this.image.getHeight() - this.font.getSize()) + this.font.getSize());
        }
        d.dispose();
        ImageIO.write(this.image, "jpeg", output);
        return checkCode;
    }

    /**
     * 生成年月日时分秒+6位随机数
     *
     * @return
     */
    public synchronized static String getNum() {
        StringBuffer sb = new StringBuffer();
        Calendar cal = new GregorianCalendar();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int date = cal.get(Calendar.DATE);
        int hour = cal.get(Calendar.HOUR);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);

        sb.append(year);
        if (month < 10) {
            sb.append("0" + month);
        } else {
            sb.append(month);
        }
        if (date < 10) {
            sb.append("0" + date);
        } else {
            sb.append(date);
        }
        if (hour < 10) {
            sb.append("0" + hour);
        } else {
            sb.append(hour);
        }
        if (minute < 10) {
            sb.append("0" + minute);
        } else {
            sb.append(minute);
        }
        if (second < 10) {
            sb.append("0" + second);
        } else {
            sb.append(second);
        }
        int num = (int) (Math.random() * 999999);// 6位随机数
        sb.append(num);
        return sb.toString();
    }

    public static final String getSysTime() {
        Date date = new Date();
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String result = sdf.format(date);
        return result;
    }

    public static final Date parseDate(String dateStr, String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat(formatStr, Locale.SIMPLIFIED_CHINESE);
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static final String getSysDate(String format) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String result = sdf.format(date);
        return result;
    }

    /**
     * 空格右填充至指定长度
     *
     * @param str
     * @param length
     * @return
     */
    public static String rightFillBlank(String str, int length) {
        StringBuilder sb = new StringBuilder();
        if (str == null) {
            str = "";
        }
        if (str.length() > length) {
            return str.substring(0, length);
        }

        sb.append(str);
        for (int i = 0; i < length - str.length(); i++) {
            sb.append(" ");
        }

        return sb.toString();
    }

    /**
     * 字符串空格处理
     *
     * @param value
     * @return
     */
    public static String trim(String value) {
        return value == null ? "" : value.trim();
    }

    /**
     * 手机号验证
     *
     * @param str
     * @return 验证通过返回true
     */
    public static boolean isMobile(String str) {
        Pattern p = null;
        Matcher m = null;
        boolean b = false;
        p = Pattern.compile("^[1][3,4,5,8][0-9]{9}$"); // 验证手机号
        m = p.matcher(str);
        b = m.matches();
        return b;
    }

    /**
     * 电话号码验证
     *
     * @param str
     * @return 验证通过返回true
     */
    public static boolean isPhone(String str) {
        Pattern p1 = null, p2 = null;
        Matcher m = null;
        boolean b = false;
        p1 = Pattern.compile("^[0][1-9]{2,3}-[0-9]{5,10}$"); // 验证带区号的
        p2 = Pattern.compile("^[1-9]{1}[0-9]{5,8}$"); // 验证没有区号的
        if (str.length() > 9) {
            m = p1.matcher(str);
            b = m.matches();
        } else {
            m = p2.matcher(str);
            b = m.matches();
        }
        return b;
    }

    /**
     * 判断email是否格式正确
     *
     * @param args
     */
    public static boolean isEmail(String email) {
        Pattern pattern = Pattern.compile("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

    /**
     * 获取隐藏的email
     *
     * @param email
     * @return
     */
    public static String getHideEmail(String email) {
        if (StringUtil.isEmpty(email)) {
            return "";
        }
        if (!email.contains("@")) {
            return email;
        }
        String emailHide = email.substring(0, email.indexOf("@"));
        String hide = "";
        if (emailHide.length() >= 7) {
            for (int i = 0, j = emailHide.length() - 6; i < j; i++) {
                hide += "*";
            }
            emailHide = emailHide.substring(0, 3) + hide
                    + emailHide.substring(emailHide.length() - 3, emailHide.length())
                    + email.substring(email.indexOf("@"), email.length());
        } else if (emailHide.length() < 7 && emailHide.length() > 3) {
            for (int i = 0, j = emailHide.length() / 2; i < j; i++) {
                hide += "*";
            }
            emailHide = emailHide.substring(0, emailHide.length() / 2) + hide
                    + email.substring(email.indexOf("@"), email.length());
        } else {
            emailHide = email;
        }
        return emailHide;
    }

    /**
     * 获取隐藏的phone
     *
     * @param phone
     * @return
     */
    public static String getHidePhone(String phone) {
        if (StringUtil.isEmpty(phone)) {
            return "";
        }
        String hidePhone = phone.substring(0, 3) + "****" + phone.substring(7, phone.length());
        return hidePhone;
    }

    /**
     * 获取字符串context中汉字的个数
     *
     * @param context 字符串
     * @return int 汉字的个数
     */
    public static int getChineseNum(String context) { // /统计context中是汉字的个数
        if (context == null)
            return 0;
        int lenOfChinese = 0;
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]"); // 汉字的Unicode编码范围
        Matcher m = p.matcher(context);
        while (m.find()) {
            lenOfChinese++;
        }
        return lenOfChinese;
    }

    /**
     * 检测字符长度
     */
    public static int stringLength(String str) {
        int chinaNum = getChineseNum(str);
        int length = str.length() + chinaNum;
        return length;
    }

    /**
     * 比较数据库长度
     *
     * @param str
     * @param oracleLength
     * @return
     */
    public static boolean checkLength(String str, int oracleLength) {
        int length = stringLength(str);
        if (length <= oracleLength) {
            return true;
        }
        return false;
    }

    /**
     * 比较数据库长度
     *
     * @param str
     * @param oracleLength
     * @return
     */
    public static boolean outOfDateLength(String str, int oracleLength) {
        int length = stringLength(str);
        if (length <= oracleLength) {
            return false;
        }
        return true;
    }

    /**
     * 获取处理之后的用户名
     *
     * @param userLogin
     * @return
     */
    public static String getHideUserName(String userName) {
        if (isEmpty(userName)) {
            return "";
        }
        if (userName.contains("@")) {
            return getHideEmail(userName);
        } else {
            return getHidePhone(userName);
        }
    }

    /**
     * 返回验证参数
     *
     * @return
     */
    public static Map<String, Object> getResult(Map<String, Object> map, String code, String msg) {
        if (map == null) {
            map = new HashMap<String, Object>();
        }
        map.put("errCode", code);
        map.put("errMsg", msg);
        return map;
    }

    public static String getHideRealName(String realName) {
        if (isEmpty(realName)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        if (realName.length() > 1) {
            sb.append("*").append(realName.substring(1, realName.length()));
        } else {
            sb.append(realName);
        }
        return sb.toString();
    }

    public static int getRandom(int begin, int end) {
        return (int) (Math.random() * (end - begin) + begin);
    }

    /**
     * BASE64加密 * @param key * @return * @throws Exception
     */
    public static String encryptBASE64(String key) {
        if (isEmpty(key)) {
            return "";
        }
        try {
            return replaceBlank((new BASE64Encoder()).encodeBuffer(key.getBytes("utf-8")).trim());
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    public static String getFilePath(String fillPath) {
        String realPath = fillPath.replaceAll("//", "/");
        realPath = realPath.replaceAll("/\\\\", "/");
        realPath = realPath.replaceAll("\\\\/", "/");
        return realPath;
    }

    /**
     * 获取隐藏银行卡号码
     *
     * @param roCardNo
     * @return
     */
    public static String getHideCardNo(String roCardNo) {
        if (isEmpty(roCardNo)) {
            return "";
        }
        if (roCardNo.length() < 16) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        sb.append(roCardNo.substring(0, 4));
        for (int i = 0; i < roCardNo.length() - 8; i++) {
            sb.append("*");
        }
        sb.append(roCardNo.substring(roCardNo.length() - 4, roCardNo.length()));
        return sb.toString();
    }

   

    /**
     * BASE64解密 * @param key * @return * @throws Exception
     */
    public static byte[] decryptBASE64(String key) {
        try {
            return (new BASE64Decoder()).decodeBuffer(key);
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 是否为纯数字
     *
     * @param str
     * @return
     */
    public static boolean checkAmt(String str) {
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("[0-9]*");
        java.util.regex.Matcher match = pattern.matcher(str.trim());
        return match.matches();
    }

    /**
     * 是否为金额
     *
     * @param str
     * @return
     */
    public static boolean isBigDecimal(String str) {
        java.util.regex.Matcher match = null;
        if (checkAmt(str) == true) {
            java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("[0-9]*");
            match = pattern.matcher(str.trim());
        } else {
            if (str.trim().indexOf(".") == -1) {
                java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^[+-]?[0-9]*");
                match = pattern.matcher(str.trim());
            } else {
                java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^[+-]?[0-9]+(\\.\\d{1,100}){1}");
                match = pattern.matcher(str.trim());
            }
        }
        return match.matches();
    }

    /**
     * 数值转换
     *
     * @param tranAmt
     * @return
     */
    public static double[] getDoubleArray(String[] tranAmt) {
        List<Double> tranAmtList = new ArrayList<Double>();
        for (int i = 0; i < tranAmt.length; i++) {
            if (!StringUtil.isEmpty(tranAmt[i])) {
                tranAmtList.add(stringToDouble(Double.valueOf(tranAmt[i]).doubleValue()));
            }
        }
        double[] tranAmtsArr = new double[tranAmtList.size()];
        for (int i = 0; i < tranAmtList.size(); i++) {
            tranAmtsArr[i] = tranAmtList.get(i).doubleValue();
        }
        return tranAmtsArr;
    }

    /**
     * 是否是数字
     *
     * @param str
     * @return
     */
    public static boolean isNumer(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 校验银行卡卡号
     *
     * @param cardId
     * @return
     */
    public static boolean checkBankCard(String cardId) {
        char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return cardId.charAt(cardId.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     *
     * @param nonCheckCodeCardId
     * @return
     */
    public static char getBankCardCheckCode(String nonCheckCodeCardId) {
        if (nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+")) {
            // 如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }

    /**
     * 四舍五入
     *
     * @param priceString
     * @return
     */
    public static double formatDouble(String priceString) throws Exception {
        double price = Double.valueOf(priceString);
        return stringToDouble(price);
    }

    /**
     * 获取随机数
     *
     * @param @return 设定文件
     * @return 返回类型
     * @throws
     * @Title:
     */
    public static double gainAmt() {
        // 生成随机数
        Integer M = 1;
        Integer N = 50;
        Integer R = (int) (M + Math.random() * (N - M)) + 100;
        Double amt = (R.doubleValue()) / 100;
        return amt;
    }

    public static JSONObject msg(JSONObject json, String retCode, String retMsg) {
        if (json == null) {
            json = new JSONObject();
        }
        json.put("retCode", retCode);
        json.put("retMsg", retMsg);
        return json;
    }

    public static JSONObject msg(String retCode, String retMsg) {
        JSONObject json = new JSONObject();
        json.put("retCode", retCode);
        json.put("retMsg", retMsg);
        return json;
    }

    public static JSONObject msg(String retCode, String retMsg, JSONObject json) {
        JSONObject result = new JSONObject();
        result.put("retCode", retCode);
        result.put("retMsg", retMsg);
        result.put("Response", json);
        return result;
    }

    public static JSONObject error(String retCode, String retMsg) {
        JSONObject json = new JSONObject();
        json.put("errCode", retCode);
        json.put("errMsg", retMsg);
        return json;
    }

    public static String getRetMsg(HttpServletRequest request) {
        String retMsg = "";
        Enumeration enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            retMsg += paraName + "=" + request.getParameter(paraName) + "&";
        }
        if (!isEmpty(retMsg)) {
            return retMsg.substring(0, retMsg.length() - 1);
        }
        return retMsg;
    }

    public static String getUrlByJson(String returnUrl, JSONObject jsonOrder) {
        if (StringUtil.isEmpty(returnUrl)) {
            return null;
        }
        if (jsonOrder == null) {
            return null;
        }
        String jsonString = JSONObject.toJSONString(jsonOrder);
        jsonString = "resJson=" + getEncodeValue(jsonString);
        // jsonString = "resJson=" + jsonString;
        if (returnUrl.contains("?")) {
            returnUrl += "&" + jsonString;
        } else {
            returnUrl += "?" + jsonString;
        }
        return returnUrl;
    }

    /**
     * 生成签名
     *
     * @param method    签名方法
     * @param result    返回参数
     * @param secretKey 商户秘钥
     * @return 签名
     */
    public static String getSign(String method, String response, String merchantNo, String secretKey) {
        MD5 md5 = new MD5();
        StringBuffer md5Str = new StringBuffer(md5.getMD5ofStr(method));
        md5Str.append("&" + md5.getMD5ofStr(response));
        md5Str.append("&" + md5.getMD5ofStr(merchantNo));
        md5Str.append("&" + md5.getMD5ofStr(secretKey));
        return md5.getMD5ofStr(md5Str.toString()).toUpperCase();
    }

    public static String formatUpopAmount(String str) {
        int len = str.length();// 取得字符串的长度
        int index = 0;// 预定义第一个非零字符串的位置
        char strs[] = str.toCharArray();// 将字符串转化成字符数组
        for (int i = 0; i < len; i++) {
            if ('0' != strs[i]) {
                index = i;// 找到非零字符串并跳出
                break;
            }
        }
        String strLast = str.substring(index, len);// 截取字符串
        return strLast;
    }



    /**
     * 处理银联金额
     *
     * @param txnAmt
     * @return
     */
    public static double formatDoubleForUPOP(String txnAmt) throws Exception {
        if (isEmpty(txnAmt)) {
            return 0;
        }
        if (txnAmt.length() < 12) {
            throw new Exception();
        }
        String start = "";
        String amtString = txnAmt.substring(txnAmt.length() - 12, txnAmt.length());
        if (amtString.length() + 1 == txnAmt.length()) {
            start = txnAmt.substring(0, 1);
        }
        double s = formatDouble(amtString) / 100;
        if ("D".equals(start)) {
            return -s;
        }
        return s;
    }

    /**
     * json返回前台信息
     */
    public static JSONObject msgFront(String code, String msg, String id) {
        JSONObject json = new JSONObject();
        json.put("retCode", code);
        json.put("retMsg", msg);
        json.put("retId", id);
        return json;
    }
}
